package com.xiaolin.structure.linked.oneway.loop;


/**
 * @ClassName OneWayLoopLinkedList
 * @Description 单向循环链表
 * @Detail detail
 * @Author MyPC
 * @Date 2020/12/12
 * @Version 1.0
 */
public class OneWayLoopLinkedList<E> {
    public int size;
    public Node<E> first;
    public Node<E> last;

    /**
     * 链接新元素
     * @param e
     */
    private void linkedElement(E e){
        if(first == null){
            // 链表为空，添加第一个元素
            first=new Node<>(e);
            // 指定最后一个节点
            last=first;
            // 构成循环
            first.next=first;
            size++;
        }else {
            // 链表不为空，添加元素到最后
            last.next=new Node<>(e);
            // 重新指定最后一个节点
            last=last.next;
            // 构成循环
            last.next=first;
            size++;
        }
    }

    /**
     * 索引校验
     * @param index
     */
    private void checkout(int index){
        if(index<0 || index >= size){
            throw new IndexOutOfBoundsException("索引越界");
        }
    }

    /**
     * 移除元素时索引校验,
     * @param index
     */
    private void checkout2(int index){
        if(index<1 || index >= size){
            throw new IndexOutOfBoundsException("索引越界");
        }
    }

    /**
     * 寻找索引的前一个元素
     * @param index
     * @return
     */
    private Node<E> getPreElement(int index){
        checkout2(index);
        Node<E> temp=first;
        for(int i=1;i<index;i++){
            temp=temp.next;
        }
        return temp;
    }

    /**
     * 寻找索引的元素
     * @param index
     * @return
     */
    private Node<E> getCurElement(int index){
        checkout(index);
        Node<E> temp=first;
        for(int i=0;i<index;i++){
            temp=temp.next;
        }
        return temp;
    }

    /**
     * 添加元素
     * @param e
     */
    public boolean add(E e){
      linkedElement(e);
      return true;
    }

    /**
     * 索引元素
     * @param index
     * @return
     */
    public E getElement(int index){
        checkout(index);
        Node<E> temp=first;
        for (int i=0;i<index;i++){
            temp=temp.next;
        }
        return temp.item;
    }

    /**
     * 删除元素
     * @param index
     * @return
     */
    public boolean remove(int index){
        checkout(index);
        if(index==0){
            // 移除第一个元素
            first=first.next;
            last.next=first;
        }else if(index==size-1){
            // 移除最后一个元素
            // 前一个元素
            Node<E> preElement = getPreElement(index);
            // 移除元素
            last=preElement;
            last.next=first;
        }else {
            // 移除中间元素
            // 前一个节点
            Node<E> preElement = getPreElement(index);
            // 要移除的元素
            Node<E> curElement = getCurElement(index);
            preElement.next=curElement.next;
        }
        size--;
        return true;
    }

}
